from typing import Any
from django.core.handlers.wsgi import WSGIRequest
from django.http import JsonResponse
from django.core.cache import caches
from django.core.paginator import Paginator
from django.db import transaction
from django.views import View


from rest_framework import status
from rest_framework.parsers import JSONParser

from warehouse.models import JuqiGood, GoodLevel
from warehouse.serializers import JuqiGoodSerializer, GoodLevelSer

from wuxianshang.models import (
    WuxianshangGameGood,
)

from wxuser.models import UserPackage
from quanjushang.models import QuanjushangGood
from yifanshang.models import YifanshangGameGood


from juqiadmin.auth import login_auth, JuqiUser, check_admin

from jqexception.jqexecption import (
    jq_try,
    UnknowErr,
    RaffleBusyErr,
    RightErr,
    NullErr,
    ReqMethodErr,
    DeleteGoodErr,
)

import logging

logger = logging.getLogger("log")
# Create your views here.


class GoodView(View):
    def setup(self, request: WSGIRequest, *args: Any, **kwargs: Any) -> None:
        super().setup(request, *args, **kwargs)

    #
    @login_auth
    def get(self, request: WSGIRequest, *args, **kwargs):
        #   req query params：
        #   - `many`  查询所有商品
        #   - `page` 分页
        #   - `num`  查询个数
        #   - `uuid`  good uuid
        #   - `name`  商品名称
        _list = request.GET.get("list", None)
        if not _list:
            # query single good
            good_uuid = request.GET.get("uuid", None)
            good_name = request.GET.get("name", None)
            g = None
            if good_uuid:
                g = (
                    JuqiGood.objects.filter(uuid=good_uuid)
                    .filter(deleted=False)
                    .first()
                )
            elif good_name:
                g = (
                    JuqiGood.objects.filter(name=good_name)
                    .filter(deleted=False)
                    .first()
                )
            if not g:
                raise NullErr
            g_s = JuqiGoodSerializer(g)
            return JsonResponse(g_s.data, status=status.HTTP_200_OK)
        else:
            page = int(request.GET.get("page", None))
            num = min(50, int(request.GET.get("num", None)))
            game_type = request.GET.get("game_type", None)
            ip_family = request.GET.get("ip_family", None)
            state = request.GET.get("state", None)

            _objs = JuqiGood.objects

            if game_type != None:
                _objs = _objs.filter(game_type=game_type)

            if ip_family != None:
                _objs = _objs.filter(ip_family=ip_family)

            if state != None:
                _objs = _objs.filter(state=state)

            all_good = _objs.filter(deleted=False)

            p = Paginator(all_good, num)
            goods = p.get_page(page).object_list
            goods_s = JuqiGoodSerializer(goods, many=True)
            return JsonResponse(goods_s.data, status=status.HTTP_200_OK, safe=False)

    @login_auth
    @transaction.atomic
    def post(self, request: WSGIRequest, *args, **kwargs):
        user: JuqiUser = kwargs.get("user_info", None)
        if user.type != "admin":
            raise RightErr

        JuqiGood.objects.select_for_update()
        g = JSONParser().parse(request)
        g_s = JuqiGoodSerializer(data=g)
        if g_s.is_valid(raise_exception=True):
            g_s.save()
            return JsonResponse(g_s.data, status=status.HTTP_201_CREATED)

        raise UnknowErr

    @login_auth
    @transaction.atomic
    def put(self, request: WSGIRequest, *args, **kwargs):
        user: JuqiUser = kwargs.get("user_info", None)
        if user.type != "admin":
            raise RightErr

        JuqiGood.objects.select_for_update()

        body: dict = JSONParser().parse(request)
        u = JuqiGood.objects.filter(uuid=body["uuid"]).filter(deleted=False).first()
        del body["uuid"]
        for k, v in body.items():
            setattr(u, k, v)
        u.clean()
        u.save()

        u_s = JuqiGoodSerializer(u)
        return JsonResponse(u_s.data, status=status.HTTP_200_OK)

    @check_admin
    @transaction.atomic
    def delete(self, request: WSGIRequest, *args, **kwargs):
        JuqiGood.objects.select_for_update()

        body: dict = JSONParser().parse(request)
        good_uuid = body["uuid"]

        """检查用户背包、游戏箱子"""
        user_package_good = UserPackage.objects.filter(good_uuid=good_uuid).filter(
            deleted=False
        )
        if user_package_good:
            raise DeleteGoodErr

        wxs_game_goods = (
            WuxianshangGameGood.objects.filter(good_uuid=good_uuid)
            .filter(deleted=False)
            .all()
        )
        if wxs_game_goods:
            raise DeleteGoodErr

        qjs_game_goods = QuanjushangGood.objects.filter(good_uuid=good_uuid).filter(
            deleted=False
        )
        if qjs_game_goods:
            raise DeleteGoodErr

        yfs_game_goods = YifanshangGameGood.objects.filter(good_uuid=good_uuid).filter(
            deleted=False
        )
        if yfs_game_goods:
            raise DeleteGoodErr

        u = JuqiGood.objects.filter(uuid=good_uuid).filter(deleted=False).first()
        u.deleted = True
        u.save()

        return JsonResponse(
            {"code": 0, "data": f"del {u['uuid']}"}, status=status.HTTP_200_OK
        )


class GoodLevelView(View):
    @login_auth
    def get(self, request: WSGIRequest, *args, **kwargs):
        u = kwargs["user_info"]
        if u.type != "admin":
            raise RightErr

        game_type = request.GET.get("game_type", None)
        limit = int(request.GET.get("limit", 10))
        curPage = int(request.GET.get("page", 1))

        _good = GoodLevel.objects.filter(deleted=False).all()
        if game_type != None:
            _good = (
                _good.filter(game_type=game_type)
                .order_by("-num")
                .order_by("-method_type")
            )

        pages = Paginator(_good, limit)
        paged = pages.page(curPage)

        game_data = GoodLevelSer(paged, many=True).data

        res = {
            "code": 0,
            "data": game_data,
            "data_count": pages.count,
            "page_count": pages.num_pages,
        }
        return JsonResponse(res, status=status.HTTP_200_OK)

    @login_auth
    @transaction.atomic
    def post(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        u = kwargs["user_info"]
        if u.type != "admin":
            raise RightErr

        body: dict = JSONParser().parse(request)
        game_s = GoodLevelSer(data=body)

        game_s.is_valid(raise_exception=True)
        game = game_s.save()

        _data = GoodLevelSer(game, many=False).data
        res = {"code": 0, "data": _data}
        return JsonResponse(res, status=status.HTTP_201_CREATED, safe=False)

    @login_auth
    @transaction.atomic
    def put(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        u = kwargs["user_info"]
        if u.type != "admin":
            raise RightErr

        body: dict = JSONParser().parse(request)
        level_uuid = body.pop("level_uuid")

        _data = GoodLevel.objects.filter(uuid=level_uuid).update(**body)

        _data = GoodLevelSer(
            GoodLevel.objects.filter(uuid=level_uuid).first(), many=False
        ).data

        res = {"code": 0, "data": _data}
        return JsonResponse(res, status=status.HTTP_200_OK, safe=False)

    @login_auth
    @transaction.atomic
    def delete(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        u = kwargs["user_info"]
        if u.type != "admin":
            raise RightErr

        body: dict = JSONParser().parse(request)
        level_uuid = body.pop("level_uuid")

        GoodLevel.objects.filter(uuid=level_uuid).update(deleted=True)
        res = {"code": 0, "msg": "删除成功"}
        return JsonResponse(res, status=status.HTTP_200_OK, safe=False)


class GoodLevelInfo(View):
    @login_auth
    def get(self, request: WSGIRequest, *args, **kwargs):
        u = kwargs["user_info"]
        if u.type != "admin":
            raise RightErr

        level_uuid = request.GET.get("level_uuid")

        game_data = GoodLevelSer(
            GoodLevel.objects.filter(uuid=level_uuid).first(), many=False
        ).data

        res = {
            "code": 0,
            "data": game_data,
        }
        return JsonResponse(res, status=status.HTTP_200_OK)


# class Game
